{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 导入算法包以及数据集\n",
    "import numpy as np\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import classification_report,confusion_matrix\n",
    "import operator\n",
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def knn(x_test, x_data, y_data, k):\n",
    "    # 计算样本数量\n",
    "    x_data_size = x_data.shape[0]\n",
    "    # 复制x_test\n",
    "    np.tile(x_test, (x_data_size,1))\n",
    "    # 计算x_test与每一个样本的差值\n",
    "    diffMat = np.tile(x_test, (x_data_size,1)) - x_data\n",
    "    # 计算差值的平方\n",
    "    sqDiffMat = diffMat**2\n",
    "    # 求和\n",
    "    sqDistances = sqDiffMat.sum(axis=1)\n",
    "    # 开方\n",
    "    distances = sqDistances**0.5\n",
    "    # 从小到大排序\n",
    "    sortedDistances = distances.argsort()\n",
    "    classCount = {}\n",
    "    for i in range(k):\n",
    "        # 获取标签\n",
    "        votelabel = y_data[sortedDistances[i]]\n",
    "        # 统计标签数量\n",
    "        classCount[votelabel] = classCount.get(votelabel,0) + 1\n",
    "    # 根据operator.itemgetter(1)-第1个值对classCount排序，然后再取倒序\n",
    "    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)\n",
    "    # 获取数量最多的标签\n",
    "    return sortedClassCount[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             precision    recall  f1-score   support\n",
      "\n",
      "          0       1.00      1.00      1.00        14\n",
      "          1       1.00      0.83      0.91        12\n",
      "          2       0.88      1.00      0.93        14\n",
      "\n",
      "avg / total       0.96      0.95      0.95        40\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 载入数据\n",
    "iris = datasets.load_iris()\n",
    "# x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2) #分割数据0.2为测试数据，0.8为训练数据\n",
    "\n",
    "#打乱数据\n",
    "data_size = iris.data.shape[0]\n",
    "index = [i for i in range(data_size)] \n",
    "random.shuffle(index)  \n",
    "iris.data = iris.data[index]\n",
    "iris.target = iris.target[index]\n",
    "\n",
    "#切分数据集\n",
    "test_size = 40\n",
    "x_train = iris.data[test_size:]\n",
    "x_test =  iris.data[:test_size]\n",
    "y_train = iris.target[test_size:]\n",
    "y_test = iris.target[:test_size]\n",
    "\n",
    "predictions = []\n",
    "for i in range(x_test.shape[0]):\n",
    "    predictions.append(knn(x_test[i], x_train, y_train, 5))\n",
    "\n",
    "print(classification_report(y_test, predictions))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[14  0  0]\n",
      " [ 0 10  2]\n",
      " [ 0  0 14]]\n"
     ]
    }
   ],
   "source": [
    "print(confusion_matrix(y_test,predictions))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
